/*****************************************************************************
* file  : test.c
* creat : apleilx
* data  : 2017/03/02
*******************************************************************************/
#define __os_obj_creat__
#include "os_obj.h"
#include "bsp_api.h"
#include "common.h"

void os_idle_task_hook(void);
/*----------------------------------------------------------------------------
 * task entry
 *---------------------------------------------------------------------------*/
void task_system(void *argument);
void modbus_task(void *argv);
void task_console(void *argument);
void gui_task(void *argument);

/*----------------------------------------------------------------------------
 *   created systask
 *---------------------------------------------------------------------------*/
int os_obj_init(void)
{
	os_obj.tid_systask = &os_obj.tcb_systask;
	rt_thread_init(
		os_obj.tid_systask, "systask",
		task_system, "argv",
		os_obj.stk_systask, SYS_TASK_STK_SIZE,
		SYS_TASK_PRIO, 10);

	rt_thread_startup(os_obj.tid_systask);

	return (0);
}

/*----------------------------------------------------------------------------
 *      systask , create befor os start
 *---------------------------------------------------------------------------*/
int os_thread_init(void)
{
	//rt_thread_idle_sethook(os_idle_task_hook);

	//-------------------------------------------------------------------------
	os_obj.tid_modbus = &os_obj.tcb_modbus;
	rt_thread_init(
		os_obj.tid_modbus, "modbus",
		modbus_task, "argv",
		os_obj.stk_modbus, TASK_MODBUS_STK_SIZE,
		TASK_MODBUS_PRIO, 10);

	os_obj.tid_console = &os_obj.tcb_console;
	rt_thread_init(
		os_obj.tid_console, "console",
		task_console, "argv",
		os_obj.stk_console, TASK_COM_CMD_STK_SIZE,
		TASK_COM_CMD_PRIO, 10);
	
	
	os_obj.tid_gui = &os_obj.tcb_gui;
	rt_thread_init(
		os_obj.tid_gui, "console",
		gui_task, "argv",
		os_obj.stk_gui, TASK_GUI_STK_SIZE,
		TASK_GUI_PRIO, 10);
		
	rt_thread_startup(os_obj.tid_modbus);
	rt_thread_startup(os_obj.tid_console);
	rt_thread_startup(os_obj.tid_gui);
	
	return (0);
}

/*----------------------------------------------------------------------------
 *   created in systask
 *---------------------------------------------------------------------------*/
int os_obj_create(void)
{
	// mutex
	os_obj.mid_malloc = &os_obj.mcb_malloc;
	rt_mutex_init(os_obj.mid_malloc, "malloc", RT_IPC_FLAG_PRIO);

	// event
	os_obj.eid_modbus = &os_obj.ecb_modbus;
	rt_event_init(os_obj.eid_modbus, "ent mb", RT_IPC_FLAG_FIFO);
	
	os_thread_init();

	return 0;
}


/*----------------------------------------------------------------------------
 *   os lock
 *---------------------------------------------------------------------------*/
void os_lock(void)
{
    rt_enter_critical();
}

void os_unlock(void)
{
    rt_exit_critical();
}

/*----------------------------------------------------------------------------
 *   task info print
 *---------------------------------------------------------------------------*/
void os_task_info_print(rt_thread_t tid)
{
	int stk, stk_used, pused, prio;
	uu64 *pstk;
	if(!tid)
		return;
	
	stk =  tid->stack_size;
	pstk = (uu64 *)(tid->stack_addr);
	stk_used = 0;
	while(*pstk == 0x2323232323232323)
	{
		stk_used += 8;
		pstk ++;
	}
	
	stk_used = stk - stk_used;
	pused = stk_used * 100 / stk;
	prio = tid->current_priority;
	
	dbg_print("stack size: %04X, stack used: %4X, <%02d%%>, prio : %2d, <== task: %s\n", 
		stk, 
		stk_used, 
		pused,
		prio,
		tid->name
	);
	
	(void) pused;
	(void) prio;
}

void os_task_info(void)
{
	dbg_puts("\n===========================================================\n");
	dbg_print("system stack used : %d %%\n", stack_used()/10);
	
	//dbg_print("task amount : %d \n", osThreadGetCount());
	
	os_task_info_print(os_obj.tid_systask);
	os_task_info_print(os_obj.tid_modbus);
	os_task_info_print(os_obj.tid_console);
}
